leetcode 二叉树总结

目录

[toc]

基本的遍历方式

前序遍历:总是先访问根节点,再左子树,最后右子树

中序遍历:总是先访问左子树,再根节点,最后右子树

后序遍历:总是先访问左子树,再右子树,最后根节点


:递归方式代码非常容易

1
2
3
4
5
6
7
8
9
10
11
12
void traversal(TreeNode *node)
{
if(!node)
{
return;
}
//此时访问node称为前序遍历
traversal(node->left);
//此时访问node称为中序遍历
traversal(node->right);
//此时访问node称为后序遍历
}

94 二叉树的中序遍历(144,145)(回到目录

递归方法1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root)
{
vector<int> res;
if(root==NULL) return res;
vector<int> temp1=inorderTraversal(root->left);
for(int i=0;i<temp1.size();i++)
{
res.push_back(temp1[i]);
}
res.push_back(root->val);
vector<int> temp2=inorderTraversal(root->right);
for(int i=0;i<temp2.size();i++)
{
res.push_back(temp2[i]);
}
return res;
}
};

递归方法2

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root)
{
if(!root) return result;
inorderTraversal(root->left);
result.push_back(root->val);
inorderTraversal(root->right);
return result;
}
private:
vector<int> result;
};

迭代方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Solution {
vector<int> res;
public:
vector<int> inorderTraversal(TreeNode* root)
{
if(root==NULL) return res;
vector<int> res;
stack<TreeNode*> s;
s.push(root);
while(!s.empty())
{
TreeNode* node=s.top();
if(node->left)
{
s.push(node->left);
node->left=NULL;
}
else
{
res.push_back(node->val);
s.pop();
if(node->right)
{
s.push(node->right);
}
}
}
return res;
}
};

144 二叉树的前序遍历

题目描述提示帮助提交记录社区讨论阅读解答
给定一个二叉树,返回它的 前序 遍历。

示例:

1
2
3
4
5
6
7
输入: [1,null,2,3]
1
\
2
/
3
输出: [1,2,3]

进阶: 递归算法很简单,你可以通过迭代算法完成吗?

递归方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root)
{
vector<int> res;
if(root==NULL)
{
return res;
}
res.push_back(root->val);
vector<int> temp1=preorderTraversal(root->left);
for(int i=0;i<temp1.size();i++)
{
res.push_back(temp1[i]);
}
vector<int> temp2=preorderTraversal(root->right);
for(int i=0;i<temp2.size();i++)
{
res.push_back(temp2[i]);
}
return res;
}
};

迭代方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root)
{
vector<int> res;
stack<TreeNode*> s;
if(root==NULL)
{
return res;
}
s.push(root);
while(!s.empty())
{
TreeNode* temp=s.top();
res.push_back(temp->val);
s.pop();
if(temp->right)
{
s.push(temp->right);
}
if(temp->left)//后压进来的后访问
{
s.push(temp->left);
}
}
return res;
}
};

145 二叉树的后序遍历

递归方法
递归1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root)
{
vector<int> res;
postorder(root,res);
return res;
}
private:
void postorder(TreeNode* root,vector<int> &res)
{
if(root==NULL)
{
return;
}
postorder(root->left,res);
postorder(root->right,res);
res.push_back(root->val);
}
};

递归2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root)
{
vector<int> res;
if(root==NULL) return res;
vector<int> temp1=postorderTraversal(root->left);
for(int i=0;i<temp1.size();i++)
{
res.push_back(temp1[i]);
}
vector<int> temp2=postorderTraversal(root->right);
for(int i=0;i<temp2.size();i++)
{
res.push_back(temp2[i]);
}
res.push_back(root->val);
return res;
}
};

迭代法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root)
{
vector<int> res;
if(root==NULL) return res;
stack<TreeNode*> s;
s.push(root);
while(!s.empty())
{
TreeNode* temp=s.top();
s.pop();
res.push_back(temp->val);
if(temp->left)
{
s.push(temp->left);
}
if(temp->right)
{
s.push(temp->right);
}
}
//vector反转的两种方式
//return vector<int>(res.rbegin(),res.rend());//vector反转方式1
reverse(res.begin(),res.end());//vector反转方式2
return res;
}
};

广度优先搜索

102 二叉树的层次遍历

非递归

分析:先建立一个queue,然后先把根节点放进去,这时候找根节点的左右两个子节点,这时候去掉根节点,此时queue里的元素就是下一层的所有节点,用一个for循环遍历它们,然后存到一个一维向量里,遍历完之后再把这个一维向量存到二维向量里,以此类推,可以完成层序遍历。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public:
vector<vector<int> > levelOrder(TreeNode *root) {
vector<vector<int> > res;
if (root == NULL) return res;
queue<TreeNode*> q;
q.push(root);
while (!q.empty()) {
vector<int> oneLevel;
int size = q.size();
for (int i = 0; i < size; ++i) {
TreeNode *node = q.front();
q.pop();
oneLevel.push_back(node->val);
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
res.push_back(oneLevel);
}
return res;
}
};

递归做法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {//递归方法
public:
vector<vector<int>> levelOrder(TreeNode* root)
{
vector<vector<int> >res;
preorder(root,res,0);
return res;
}
private:
void preorder(TreeNode* root,vector<vector<int> > &res,int depth)
{
if(root==NULL) return;
if(depth==res.size())
{
res.push_back(vector<int>());
}
res[depth].push_back(root->val);
preorder(root->left,res,depth+1);
preorder(root->right,res,depth+1);
}
};

构造二叉树

例如105,106都是这类问题

二叉树的平衡

108 将有序数组转换为二叉搜索树(回到目录

将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。

本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

示例:

给定有序数组: [-10,-3,0,5,9],

一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:

1
2
3
4
5
0
/ \
-3 9
/ /
-10 5

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* sortedArrayToBST(vector<int>& nums)
{
if(nums.size()==0) return NULL;
if(nums.size()==1) return new TreeNode(nums[0]);
int mid=nums.size()/2;
TreeNode* root=new TreeNode(nums[mid]);
vector<int> left(nums.begin(),nums.begin()+mid);
vector<int> right(nums.begin()+mid+1,nums.end());
root->left=sortedArrayToBST(left);
root->right=sortedArrayToBST(right);
return root;
}
};

109 有序链表转换二叉搜索树

给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。

本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

使用了递归,和那个24题差不多,关键是如何找到链表的中间位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution {//使用了递归,和那个24题差不多
public:
TreeNode* sortedListToBST(ListNode* head)
{
if(head==NULL) return NULL;
else if(head->next==NULL)
{
return (new TreeNode(head->val));
}
ListNode* fast=head->next->next;
ListNode* slow=head;
while(fast && fast->next)//这段代码是在找链表中间位置的元素
{
fast=fast->next->next;
slow=slow->next;
}
TreeNode* root=new TreeNode(slow->next->val);//这就是找到的中间位置
printf("%d\n",root->val);
root->right=sortedListToBST(slow->next->next);
slow->next=NULL;
root->left=sortedListToBST(head);
return root;
}
};

110 平衡二叉树(回到目录

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:

一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。

示例 1:

1
2
3
4
5
6
7
8
给定二叉树 [3,9,20,null,null,15,7]
3
/ \
9 20
/ \
15 7
返回 true 。

示例 2:

1
2
3
4
5
6
7
8
9
10
给定二叉树 [1,2,2,3,3,null,null,4,4]
1
/ \
2 2
/ \
3 3
/ \
4 4
返回 false 。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public:
bool isBalanced(TreeNode* root)
{
if(root==NULL) return true;
if(abs(depth(root->left)-depth(root->right))>1)
{
return false;
}
return isBalanced(root->left)&&isBalanced(root->right);
}
private:
int depth(TreeNode* root)
{
if(root==NULL) return 0;
return 1+max(depth(root->left),depth(root->right));
}
};

-------------本文结束感谢您的阅读-------------
您的小小鼓励,是我不断更新的强大动力!